﻿using Sidvall.Security;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Security.Principal;

namespace Sidvall.Web.Security
{
	public abstract class ValidatorBase
	{
		#region Public Members

		#region AuthenticationManager

		private AuthenticationManager _AuthenticationManager;
		public AuthenticationManager AuthenticationManager
		{
			get
			{
				if (_AuthenticationManager != null)
					return _AuthenticationManager;
				return Sidvall.SystemContext.Current.AuthenticationManager;
			}
			set
			{
				_AuthenticationManager = value;
			}
		}

		#endregion
		#region ClaimManager

		private ClaimManager _ClaimManager;
		public ClaimManager ClaimManager
		{
			get
			{
				if (_ClaimManager != null)
					return _ClaimManager;
				return Sidvall.SystemContext.Current.ClaimManager;
			}
			set
			{
				_ClaimManager = value;
			}
		}

		#endregion
		#region IgnoredUsers

		private System.Collections.ObjectModel.Collection<string> _IgnoredUsers;
		public System.Collections.ObjectModel.Collection<string> IgnoredUsers
		{
			get
			{
				if (_IgnoredUsers == null)
					return _IgnoredUsers = new System.Collections.ObjectModel.Collection<string>();
				return _IgnoredUsers;
			}
		}

		#endregion

		#region IsIgnored

		protected bool IsIgnored(IIdentity identity, NameValueCollection formValues)
		{
			if ((identity != null) && (this.IgnoredUsers.Count > 0))
			{
				var value = this.ClaimManager.FindClaimValue(identity, Sidvall.Security.ClaimTypes.Subject);
				if (string.IsNullOrWhiteSpace(value))
				{
					var identityToken = GetIdentityToken(identity, formValues);
					if (identityToken != null)
						value = identityToken.Subject;
				}
				if (!string.IsNullOrWhiteSpace(value))
				{
					if (this.IgnoredUsers.Contains(value))
						return true;
				}
			}
			return false;
		}

		#endregion
		#region GetIdentityToken

		protected Sidvall.Security.IdentityToken GetIdentityToken(IIdentity identity, NameValueCollection formValues)
		{
			Sidvall.Security.IdentityToken item;
			string token;

			if (formValues != null)
			{
				token = formValues[Sidvall.Security.ClaimTypes.IdentityToken];
				item = this.AuthenticationManager.ParseIdentityTokenFromToken(token);
				if (item != null)
					return item;
			}
			if (identity != null)
			{
				token = this.ClaimManager.FindClaimValue(identity, Sidvall.Security.ClaimTypes.IdentityToken);
				item = this.AuthenticationManager.ParseIdentityTokenFromToken(token);
				if (item != null)
					return item;
			}
			return null;
		}

		#endregion

		#endregion
		#region Constructors

		protected ValidatorBase()
		{
		}
		protected ValidatorBase(IEnumerable<string> ignoredUsers)
		{
			if (ignoredUsers != null)
			{
				foreach (var ignoredUser in ignoredUsers)
					this.IgnoredUsers.Add(ignoredUser);
			}
		}

		#endregion
	}
}
